#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <fstream>
// 必须包含 SM4.h 来获取 SM4_Encrypt 和 SM4_Decrypt 的声明
#include "SM4.h" 

using namespace std;

// 打印十六进制工具函数
void print_hex(const unsigned char *data, int len) {
    for (int i = 0; i < len; i++)
        // 使用 setw(2) 和 setfill('0') 确保每个字节都输出两位
        cout << hex << setw(2) << setfill('0') << (int)data[i];
    cout << dec << endl;
}

int main() {
    cout << "--- 自实现 SM4 单块加解密测试 ---" << endl;
    
    // 标准测试密钥
    unsigned char key[16] = {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
        0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
    };

    // 明文（16字节）
    unsigned char input[16]  = {'T','e','s','t','S','M','4','_','C','h','e','c','k','!','!','!'};
    unsigned char enc[16]    = {0}; // 密文缓冲区
    unsigned char dec[16]    = {0}; // 解密后明文缓冲区

    cout << "原始明文: " << string((char*)input, 16) << endl;

    // === 自实现 SM4 加密 (ECB 模式) ===
    // 函数签名：void SM4_Encrypt(unsigned char MK[], unsigned char PlainText[], unsigned char CipherText[]);
    SM4_Encrypt(key, input, enc);
    cout << "SM4 加密结果: ";
    print_hex(enc, 16);

    // === 自实现 SM4 解密 (ECB 模式) ===
    // 函数签名：void SM4_Decrypt(unsigned char MK[], unsigned char CipherText[], unsigned char PlainText[]);
    SM4_Decrypt(key, enc, dec);
    cout << "SM4 解密结果: " << string((char*)dec, 16) << endl;
    
    // === 自检功能调用 ===
    cout << "\n--- 调用 SM4_SelfCheck ---" << endl;
    if (SM4_SelfCheck() == 0) {
        cout << "✅ SM4_SelfCheck 成功通过标准测试向量！" << endl;
    } else {
        cout << "❌ SM4_SelfCheck 未通过标准测试向量！请检查 SM4.cpp 中的实现。" << endl;
    }

    // === 写入文件供 GmSSL 验证 ===
    cout << "\n--- 外部工具 GmSSL 验证 (ECB) ---" << endl;
    ofstream fout("gmssl_plain.bin", ios::binary);
    fout.write((char*)input, 16);
    fout.close();

    // GmSSL 默认使用 ECB 模式进行单块加密对比
    int ret = system(
        "gmssl sm4_ecb -encrypt "
        "-key 0123456789abcdeffedcba9876543210 "
        "-in gmssl_plain.bin -out gmssl_cipher.bin"
    );

    if (ret != 0) {
        cerr << "❌ GmSSL 执行失败，请确认 GmSSL 已安装且路径正确。" << endl;
        system("rm -f gmssl_plain.bin gmssl_cipher.bin");
        return 1;
    }

    // 读取 GmSSL 生成的密文
    unsigned char gmssl_out[16] = {0};
    ifstream fin("gmssl_cipher.bin", ios::binary);
    if (!fin.is_open()) {
        cerr << "❌ 无法打开 GmSSL 输出文件进行比较。" << endl;
        system("rm -f gmssl_plain.bin gmssl_cipher.bin");
        return 1;
    }
    fin.read((char*)gmssl_out, 16);
    fin.close();

    cout << "GmSSL 加密结果: ";
    print_hex(gmssl_out, 16);

    // === 比较结果 ===
    if (memcmp(enc, gmssl_out, 16) == 0)
        cout << "✅ 验证成功：自实现 SM4 (ECB) 与 GmSSL (ECB) 结果一致！" << endl;
    else
        cout << "❌ 验证失败：结果不一致！请检查 SM4.cpp 中的实现细节。" << endl;
    
    // 清理临时文件
    system("rm -f gmssl_plain.bin gmssl_cipher.bin");

    return 0;
}
